package com.rh.redis.token;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @author 57556
 */
@Component
@ConfigurationProperties(value = "token")
@Data
public class JavaWebToken {
    private static Logger log = LoggerFactory.getLogger(JavaWebToken.class);
    /**
     * 获取加密字符串 加密token
     */
    private String encryption = "renHai";

    /**
     * 该方法使用HS256算法和Secret:bankgl生成signKey
     */
    private static Key getKeyInstance() {
        //We will sign our JavaWebToken with our ApiKey secret
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //加密，里面的字符串可自行定义
        JavaWebToken token = new JavaWebToken();
        ;
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(token.getEncryption());
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        return signingKey;
    }

    /**
     * 使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
     *
     * @param id 待转化的数据
     * @return token字符串
     */
    public static String createJavaWebToken(String id) {
        Map<String, Object> claims = new HashMap<>(2);
        //用户id
        claims.put("id", id);
        //token创建时间
        claims.put("createTime", LocalDateTime.now());
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        return Jwts.builder()
                .setClaims(claims)
                //超时时间，设置为7天
                .setExpiration(new Date(nowMillis + 1000 * 60 * 60 * 24 * 7))
                .setIssuedAt(now)
                .setNotBefore(now)
                .signWith(SignatureAlgorithm.HS256, getKeyInstance())
                .compact();
    }

    /**
     * 解析Token，同时也能验证Token，当验证失败返回null
     *
     * @param jwt token字符串
     * @return 解析的数据
     */
    public static Map<String, Object> parserJavaWebToken(String jwt) {
        try {
            Map<String, Object> jwtClaims =
                    Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
            return jwtClaims;
        } catch (Exception e) {
            log.error("json web token verify failed : " + e.getMessage());
            return null;
        }
    }
}
